package com.yupi.springbootinit.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.yupi.springbootinit.mapper.ChartMapper;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.service.ChartService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author boss
 * @description 针对表【chart(图表信息表)】的数据库操作Service实现
 * @createDate 2024-01-16 18:18:31
 */
@Service
@Slf4j
public class ChartServiceImpl extends ServiceImpl<ChartMapper, Chart> implements ChartService {
    @Resource
    ChartMapper chartMapper;

    @Override
    public boolean createAndInsert(Long id, List<Map<Integer, String>> tableList) {
        //校验参数
        if (id == null || CollUtil.isEmpty(tableList)) {
            return false;
        }
        //创建表
        LinkedHashMap<Integer, String> headerMap = (LinkedHashMap<Integer, String>) tableList.get(0);
        List<String> headerList = headerMap.values().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        boolean isCreateRawDataTable = createRawDataTable(id, headerList);

        int effectNum = 0;
        //插入数据
        for (int i = 1; i < tableList.size(); i++) {
            LinkedHashMap<Integer, String> dataMap = (LinkedHashMap<Integer, String>) tableList.get(i);
            //            List<String> dataList = dataMap.values().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
            List<String> dataList = new ArrayList<>(dataMap.values());
            effectNum += insertSingleRawData(id, dataList, headerList.size());
        }
        return isCreateRawDataTable && effectNum == tableList.size() - 1;
    }

    @Override
    public List<LinkedHashMap<String, Object>> selectChartRawData(Long id) {
        String sql = "select * from chart_%s";
        return chartMapper.queryChartData(String.format(sql, id));
    }

    @Override
    public int upDateChartRawData(Long id, List<LinkedHashMap<String, Object>> modifiedData) {
        //1确定要修改的表
        //2.1查修改前的数据
        List<LinkedHashMap<String, Object>> updateBeforeRawDataList = selectChartRawData(id);
        if (updateBeforeRawDataList == null || updateBeforeRawDataList.size() <= 0) { //表不存在或表数据为空
            return 0;
        }
        if (modifiedData.size() != updateBeforeRawDataList.size()) { //暂时只允许修改，不允许新增和删除 todo
            return 0;
        }
        int updateResultCnt = 0;
        for (int i = 0; i < updateBeforeRawDataList.size(); i++) {  //遍历每一条记录，i为行数
            //2.2对比修改前和修改后数据的差异项
            LinkedHashMap<String, Object> beforeMap = updateBeforeRawDataList.get(i);//修改前：1 10
            LinkedHashMap<String, Object> afterMap = modifiedData.get(i);//修改后：1 20
            MapDifference<String, Object> difference = Maps.difference(beforeMap, afterMap);
            Map<String, MapDifference.ValueDifference<Object>> entriesDiffering = difference.entriesDiffering();// 找出更新后的键值对
            MapDifference.ValueDifference<Object> idMapDifference = entriesDiffering.get("id");
            if (idMapDifference == null) {
                return 0;
            }
            //2确定要修改的行id
            long colId = (long) idMapDifference.leftValue();
            for (Map.Entry<String, MapDifference.ValueDifference<Object>> entry : entriesDiffering.entrySet()) {
                String title = entry.getKey();
                Object beforeValue = entry.getValue().leftValue();
                Object afterValue = entry.getValue().rightValue();
                if (String.valueOf(beforeValue).equals(String.valueOf(afterValue))) { //此时数据没有更新，不更改
                    continue;
                }

                //3局部更新原始数据
                //update chart_1747189249993633793 set 用户数 = 20 where id = 1;
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("update chart_").append(id).append(" set `").append(title).append("` = ").append("'").append(afterValue).append("'").append(" where id = ").append(colId).append(";");
                log.info(sqlBuilder.toString());
                int updateResult = chartMapper.updateRawData(sqlBuilder.toString());
                updateResultCnt += updateResult;
            }
        }
        return updateResultCnt;
    }

    public int addIdCol(Long id) {
        //        alter table chart_1774290833160278018 add id bigint not null auto_increment primary key;
        return chartMapper.addIdCol("alter table chart_" + id + " add id bigint not null auto_increment primary key;");
    }

    private boolean createRawDataTable(Long id, List<String> headList) {
        if (id == null || CollUtil.isEmpty(headList)) {
            return false;
        }
        StringBuilder createTableSql = new StringBuilder();
        createTableSql.append("create table if not exists bi_db.`chart_").append(id).append("` ").append("( ");
        StringBuilder cloSql = new StringBuilder();
        for (String head : headList) {
            cloSql.append("`").append(head).append("` ").append("varchar(128) ").append("null ").append(",");
        }
        //去掉最后一个“,"
        cloSql.replace(cloSql.length() - 1, cloSql.length(), "");
        createTableSql.append(cloSql).append(") collate = utf8mb4_unicode_ci;");
        String completedCreateTableSql = createTableSql.toString();

        //todo createChartRawDataTable返回值？
        boolean isCreateTable = chartMapper.createChartRawDataTable(completedCreateTableSql);
        int addIdColResult = addIdCol(id);
        return true;
    }

    private int insertSingleRawData(Long id, List<String> dataList, int headerLength) {
        if (id == null || CollUtil.isEmpty(dataList)) {
            return 0;
        }
        //        insert into graduationproject.`t_organization` (`id`, `o_name`, `o_code`, `o_category`, `o_entered`, `o_username`, `o_phone`, `is_deleted`) values ('tE99W', '广西医科大学', '173.87.145.115', 'PHP', '81', '崔志泽', '15531796954', '0');
        StringBuilder insertDataSql = new StringBuilder();
        insertDataSql.append("insert into bi_db.`chart_").append(id).append("` VALUES (");
        StringBuilder itemSql = new StringBuilder();
        //headerLength 使表头和数据一一对齐
        for (int i = 0; i < headerLength; i++) {
            itemSql.append("'").append(dataList.get(i)).append("'").append(",");
        }
        //去掉最后一个“,"
        itemSql.replace(itemSql.length() - 1, itemSql.length(), "");
        insertDataSql.append(itemSql).append(");");
        String completedInsertDataSql = insertDataSql.toString();
        return chartMapper.insertChartData(completedInsertDataSql);
    }
}




